package com.athena.api.messaging;

import com.athena.api.model.Page;
import com.athena.api.model.messaging.Conversation;
import com.athena.api.model.messaging.Message;
import com.athena.api.model.messaging.MessageContent;
import com.athena.api.model.messaging.Post;
import com.athena.api.model.messaging.PostContent;
import com.athena.dal.entities.User;
/**
 * @author vikas
 *
 * Athena as a solution to Academic problems at level of School involves certain distinct participants.
 * Distinct Participants involved are Students, Faculty, Admin, Parents  and some Abstract Participants
 * like Class, Labs, Houses, School.
 * 
 * Messaging Service is a core service for Athena. Service handles all types of communication among all 
 * the participants. The communication here are asynchronous non-real time. Messages are basically persistent
 * entities. All conversations are persisted for monitoring purposes. Messages are of two types 
 * 1. point-to-point refers as simple Messages and 2. broadcasting type referred as Posts. 
 * 
 * All messaging among Real Participants are bidirectional(may be govern by roles on the upper layer). 
 * Messages(Point - 2 - Point Message) are private in nature and is only visible to recipients and sender. 
 * 
 * Posts( BroadCast Message ) is unidirectional in nature and takes place from Real Participant 
 * to Abstract Participant. Anything posted to Abstract Participant is broadcasted to all the 
 * subscribed Real Participants. So this communication takes in two steps. from sender
 * to Abstract Partp. and then it is broadcasted to all subscribed users. Subscription is defined in the Messaging 
 * System as two types implicit subscription (this is forced on Real Participants) and the other is explicit 
 * subscription which works on Real Participant Will.
 * 
 * Deletion of messages works on a flag basis i.e messages are never deleted actually.
 * Messages can be deleted by both the recipients and sender from their Inbox and SentBox 
 * respectively. 
 * 
 * Abstract Participants can also be referred to a group of Real Participants, so that we could 
 * realize the group feature.
 * From here Abstract Participants will be referred as Group
 */
public interface MessageService {
	
		/**
		 * @param sender is the currently logged in user or Active user in case of more than one roles
		 * @param recipient could be any user authorise to use Athena
		 * @param message content to be send
		 */
        boolean send(User sender, User recipient, MessageContent messageContent);
        boolean send(User sender, User [] recipients, MessageContent messageContent);
        
        /**
         * @param user   currently logged in user or active user. 
         * 			     should have sufficient privileges to post on that group
         * @param iGroup abstract entity on which message is posted 
         * @param post   form of messages generally publicly viewable 
         */
        void post(User user, IGroup iGroup, PostContent postContent);
        
        /**
         * explicit subscription from a user to a group
         * @param user
         * @param iGroup
         */
        void subscribe(User user, IGroup iGroup);
        
        /**
         * removing the explicit subscription from a group for the user
         * @param user
         * @param iGroup
         */
        void unsubscribe(User user, IGroup iGroup);
        
        /**
         * Fetch messages from the user's inbox
         * @param user
         * @return
         * @
         */
        Message[] fetchInBoxMessages(User user, Page page);
        
        /**
         * Fetch messages from the user's SentBox
         * @param user
         * @return
         */
        Message[] fetchSentMessages(User user, Page page);
        
        /**
         * Fetch all the conversation among the sender and recipient              
         * @param sender
         * @param recipient
         * @return
         */
        Conversation fetchConversation(User sender, User recipient, Page page);
        
        /**
         * Fetch all posts posted on Group
         * @param iDesk
         * @return Post[]
         * @
         */
        Post[] fetchPosts(IGroup iGroup, Page page) ;
        
       /**
        * delete the Post
        * @param user
        * @param post
        */
        boolean deletePost(User user, Post post);
        boolean updatePost(User user, Post post);
        
        /**
         * delete Message from user's inbox
         * @param user
         * @param message
         */
        void deleteInboxMessage(User user, Message message) ;
        
        /**
         * delete Message from user's inbox
         * @param user
         * @param message
         */
        void deleteSentMessage(User user, Message message) ;
        
        /**
         * fetch all posts subscribed by the user includes both implicit and explicit subscription
         * @param user
         * @return
         * @
         */
        Post[] fetchSubscribedPosts(User user, Page page) ;
        
        /**
         * fetch all posts from iDesk (public desk) for user if user has subscribed for that
         * @param user
         * @param iDesk
         * @return
         * @
         */
        Post[] fetchSubscribedPosts(User user, IGroup iGroup, Page page) ;
        
        /**
         * fetch all the subscriptions made by the user 
         * @param user
         * @return
         */
        IGroup [] fetchSubscribtions(User user) ;
        
        IGroup [] fetchExplicitSubscribtions(User user) ;
}
